﻿using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;

namespace XHXTools
{
    /// <summary>
    /// ftp管理类——处理具体的业务
    /// </summary>
    public class FtpManager
    {
        /// <summary>
        /// ftp信息私有成员变量
        /// </summary>
        private FtpNetModel Fnm { get; set; }

        private FtpTool ftpTool { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="fnm">ftp信息实体类对象</param>
        public FtpManager(FtpNetModel fnm)
        {
            Fnm = fnm;
            ftpTool = new FtpTool(Fnm);
        }



        /// <summary>
        /// 上传文件（只试用上传小文件对象）
        /// </summary>
        /// <param name="filePath">文件路径——[不含IP和端口][不含文件名]</param>
        /// <param name="fileName">文件名称——[不含文件后缀][用于重命名文件名]，没有则默认为当前原文件名称</param>
        /// <returns>成功：上传成功后返回目录路径[不含IP和端口]，失败：返回空 或 null</returns>
        public string FtpUploadFile(string filePath, string fileName = null)
        {
            //定义ftp全路径地址
            string address = string.Empty;
            try
            {
                //有文件名————设置当前名称为文件名称
                if (!string.IsNullOrEmpty(fileName))
                    filePath = $"{filePath}/{fileName}{Fnm.IFile.FileName.Substring(Fnm.IFile.FileName.IndexOf('.'))}";
                else//无文件名，默认原文件名
                    filePath = $"{filePath}/{Fnm.IFile.FileName.ToString()}";
                address = $"ftp://{Fnm.IP}:{Fnm.FTP_PORT}/{filePath}";  //ftp地址全路径
                int resultCode = ftpTool.FtpUploadFile(address);//调用具体上传方法
                if (resultCode == 226)
                {
                    return $"{filePath}";//上传成功后返回目录路径[不含IP和端口]
                }
                return null;
            }
            catch (Exception ex)
            {
                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string msg = $"时间：【{time}】\n\t FTP上传文件（小文件）时出现错误，具体信息：{ex.Message}\n";
                RWTextToFile.WriterLog(msg, Path.Combine(AppContext.BaseDirectory, "Logs"), "FtpErrLog.log");
                throw ex;
            }
        }

        /// <summary>
        /// 上传文件(字节流)
        /// </summary>
        /// <param name="bt">文件流</param>
        /// <param name="filePath">文件路径——[不含IP和端口][不含文件名]</param>
        /// <param name="fileName">文件名称——[包含文件后缀名]——用于重命名文件名</param>
        /// <returns>成功：返回端口后面的全路径，失败：返回空 null</returns>
        public string FtpUploadFile(byte[] bt, string filePath, string fileName)
        {
            //定义ftp全路径地址
            string address = string.Empty;
            try
            {
                filePath = $"{filePath}/{fileName}";
                address = $"ftp://{Fnm.IP}:{Fnm.FTP_PORT}/{filePath}";  //ftp地址全路径
                string resultCode = ftpTool.FtpUploadFile(bt, address).ToString();//调用具体上传方法
                if (resultCode.Contains("226"))
                {
                    return $"{filePath}";//上传成功返回端口后面的地址路径
                }
                return null;
            }
            catch (Exception ex)
            {
                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string msg = $"时间：【{time}】\n\t FTP上传文件（字节流）时出现错误，具体信息：{ex.Message}\n";
                RWTextToFile.WriterLog(msg, Path.Combine(AppContext.BaseDirectory, "Logs"), "FtpErrLog.log");
                throw ex;
            }
        }

        /// <summary>
        /// 下载文件(字节流)
        /// </summary>
        /// <param name="filePath">文件路径——[不含IP和端口][不含文件名]</param>
        /// <param name="fileName">文件名称——[包含文件后缀名]——用于重命名文件名</param>
        /// <returns>返回数据流Stream</returns>
        public Stream FtpDownloadFile(string filePath, string fileName)
        {
            //定义ftp全路径地址
            string address = string.Empty;
            try
            {
                filePath = $"{filePath}/{fileName}";
                address = $"ftp://{Fnm.IP}:{Fnm.FTP_PORT}/{filePath}";  //ftp地址全路径
                Stream stream = ftpTool.FtpDownloadFile(address);//调用具体下载方法

                return stream;
            }
            catch (Exception ex)
            {
                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string msg = $"时间：【{time}】\n\t FTP下载文件（字节流）时出现错误，具体信息：{ex.Message}\n";
                RWTextToFile.WriterLog(msg, Path.Combine(AppContext.BaseDirectory, "Logs"), "FtpErrLog.log");
                throw ex;
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="filePath">文件路径——[不含IP和端口][含文件名]</param>
        public bool FtpDeleteFile(string filePath)
        {
            //定义ftp全路径地址
            string address = string.Empty;
            try
            {
                address = $"ftp://{Fnm.IP}:{Fnm.FTP_PORT}/{filePath}";  //ftp地址全路径
                int code = ftpTool.FtpDeleteFile(address);//调用具体删除方法
                return code == 250 ? true : false;

            }
            catch (Exception ex)
            {
                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string msg = $"时间：【{time}】\n\t FTP删除文件时出现错误，具体信息：{ex.Message}\n";
                RWTextToFile.WriterLog(msg, Path.Combine(AppContext.BaseDirectory, "Logs"), "FtpErrLog.log");
                throw ex;
            }
        }

        /// <summary>
        /// 删除目录——需保证当前目录内容为空
        /// </summary>
        /// <param name="filePath">文件路径——端口号后面文件名前面的路径</param>
        /// <param name="fileName">文件名称(包含后缀名)</param>
        public void FtpDeleteFolder(string filePath, string fileName)
        {
            //定义ftp全路径地址
            string address = string.Empty;
            try
            {
                filePath = $"{filePath}/{fileName}";
                address = $"ftp://{Fnm.IP}:{Fnm.FTP_PORT}/{filePath}";  //ftp地址路径
                ftpTool.FtpDeleteFolder(address);//调用具体删除方法

            }
            catch (Exception ex)
            {
                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string msg = $"时间：【{time}】\n\t FTP删除目录时出现错误，具体信息：{ex.Message}\n";
                RWTextToFile.WriterLog(msg, Path.Combine(AppContext.BaseDirectory, "Logs"), "FtpErrLog.log");
                throw ex;
            }
        }

        /// <summary>
        /// 判断目录(或文件)是否存在
        /// </summary>
        /// <param name="filePath">文件路径——端口号后面文件名前面的路径</param>
        /// <param name="folderOrFile">需要判断的-文件(文件包含后缀名)或目录</param>
        /// <returns>存在：true，不存在false</returns>
        public bool IsExistsFolder(string filePath, string folderOrFile)
        {
            //定义ftp路径地址
            string address = string.Empty;
            try
            {
                address = $"ftp://{Fnm.IP}:{Fnm.FTP_PORT}/{filePath}";  //ftp地址路径
                bool flag = ftpTool.IsExistsFolder(address, folderOrFile);//调用具体判断方法

                return flag;
            }
            catch (Exception ex)
            {
                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string msg = $"时间：【{time}】\n\t FTP判断目录时出现错误，具体信息：{ex.Message}\n";
                RWTextToFile.WriterLog(msg, Path.Combine(AppContext.BaseDirectory, "Logs"), "FtpErrLog.log");
                throw ex;
            }
        }


        /// <summary>
        /// 移动  或   改名
        /// [不含IP和端口]
        /// [不含IP和端口]
        /// </summary>
        /// <param name="oldAddress">旧目录[不含IP和端口]</param>
        /// <param name="newAddress">新目录[不含IP和端口]</param>
        /// <returns>成功：true，失败：false</returns>
        public bool MoveOrRename(string oldAddress, string newAddress)
        {
            try
            {
                oldAddress = $"ftp://{Fnm.IP}:{Fnm.FTP_PORT}/{oldAddress}";
                int code = ftpTool.MoveOrRename(oldAddress, newAddress);

                return code == 250 ? true : false;
            }
            catch (Exception ex)
            {
                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string msg = $"时间：【{time}】\n\t FTP移动（重命名）文件时出现错误，具体信息：{ex.Message}\n";
                RWTextToFile.WriterLog(msg, Path.Combine(AppContext.BaseDirectory, "Logs"), "FtpErrLog.log");
                throw ex;
            }
        }

        /// <summary>
        /// 获取文件列表——[不含IP][不含端口][不含文件名]
        /// </summary>
        /// <param name="address">ftp地址——[不含IP][不含端口][不含文件名]</param>
        /// <returns></returns>
        public List<string> GetFileList(string address)
        {
            try
            {
                address = $"ftp://{Fnm.IP}:{Fnm.FTP_PORT}/{address}";
                List<string> list=ftpTool.GetFileList(address);
       
                return list;
            }
            catch (Exception ex)
            {
                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string msg = $"时间：【{time}】\n\t FTP获取文件列表时出现错误，具体信息：{ex.Message}\n";
                RWTextToFile.WriterLog(msg, Path.Combine(AppContext.BaseDirectory, "Logs"), "FtpErrLog.log");
                throw ex;
            }
        }
    }
}
